package com.easylinkin.linkappapi.security.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.easylinkin.bases.redis.util.RedisUtil;
import com.easylinkin.linkappapi.annotation.CommonOperateLogAnnotate;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.common.utils.async.AsyncUtil;
import com.easylinkin.linkappapi.common.utils.excel.ExcelConstant;
import com.easylinkin.linkappapi.common.utils.excel.ExcelTools;
import com.easylinkin.linkappapi.common.utils.io.OutputStreamUtil;
import com.easylinkin.linkappapi.common.utils.message.SendMessageUtil;
import com.easylinkin.linkappapi.lobar.dto.excel.ExcelResultDTO;
import com.easylinkin.linkappapi.operatelog.LogHelper;
import com.easylinkin.linkappapi.operatelog.constant.LogConstant.LogModule;
import com.easylinkin.linkappapi.operatelog.constant.LogConstant.LogOperateType;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappRole;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.security.entity.LinkappUserDTO;
import com.easylinkin.linkappapi.security.entity.UserRefRoleDTO;
import com.easylinkin.linkappapi.security.mapper.LinkappUserMapper;
import com.easylinkin.linkappapi.security.service.LinkappUserService;
import com.easylinkin.linkappapi.tenant.sevice.impl.LinkappTenantServiceImpl;
import com.easylinkin.sm.dto.ResetPasswordVo;
import com.easylinkin.sm.entity.Role;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import site.morn.boot.data.DisplayableControllerSupport;
import site.morn.core.CriteriaMap;
import site.morn.log.OperateArguments;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;
import site.morn.rest.RestModel;
import site.morn.validate.group.Delete;
import site.morn.validate.group.Put;
import site.morn.validate.group.Update;

/**
 * 用户控制器
 *
 * @author timely-rain
 * @since 1.0.0, 2017/9/28
 */
@Api(tags = "用户管理")
@RestController
@RequestMapping("/linkappUser")
public class LinkappUserController extends
    DisplayableControllerSupport<LinkappUser, Long, LinkappUserService> {

  /**
   * 普通用户的默认密码
   */
  private static final String DEFAULT_PSW = "abc@123";
  @Resource
  LinkappUserContextProducer linkappUserContextProducer;

  @Resource
  protected LinkappUserMapper linkappUserMapper;

  @Autowired
  RedisUtil redisUtil;
  @Autowired
  SendMessageUtil sendMessageUtil;
  @Resource
  private LinkappUserService linkappUserService;

  @Resource
  private LinkappTenantServiceImpl linkappTenantService;


  @ApiOperation("根据手机号查询全局的用户")
  @PostMapping("getUsersByPhoneGlobal")
  public RestMessage getUsersByPhoneGlobal(@RequestBody RestModel<LinkappUser> restModel) {
    LinkappUser user = restModel.getModel();
    Assert.notNull(user, "参数为空");
    Assert.notNull(user.getPhone(), "手机号为空");
    user.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    linkappUserService.validRepeat(user);
    LinkappUser query = new LinkappUser();
    query.setPhone(user.getPhone());
    List<LinkappUser> result = linkappUserService.selectUsers(query);
    //  要求只返回一个
    if (result.size() > 1) {
      result = new ArrayList<>(Collections.singleton(result.get(0)));
    }
    return RestBuilders.successBuilder().data(result).build();
  }


  /**
   * 新增
   */
  @ApiOperation("新增")
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "新增用户")
  @PostMapping("add")
//    @Override
  public RestMessage add(@RequestBody RestModel<LinkappUser> restModel,
      @RequestParam("isAddExist") Boolean isAddExist) {
    LinkappUser user = restModel.getModel();
    user.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    user.setType("2");
    user = initAndCheck(user, isAddExist);
    restModel.setModel(user);
    return super.add(restModel);
  }

    /**
     * 初始化用户
     *
     * @param user       vo
     * @param isAddExist 是否是添加已存在模式
     * @return
     */
    private LinkappUser initAndCheck(LinkappUser user, Boolean isAddExist) {
        Assert.hasLength(user.getPhone(), "手机号不能为空");
        if (user.getAddress() != null) {
            Assert.isTrue(user.getAddress().length() <= 255, "单位长度应小于255");
        }
//        检查此手机号在此租户下不存在
        linkappUserService.validRepeat(user);
        if (isAddExist) {
            LinkappUser oldUser = linkappUserService.findByUsername(user.getUsername());
            Assert.notNull(oldUser, "根据用户名查找原用户不存在：" + user.getUsername());
            user.setPassword(oldUser.getPassword());
        } else {
//            新增新用户使用默认密码
            user.setPassword(DEFAULT_PSW);
//            校验手机号全局唯一
            LinkappUser query = new LinkappUser();
            query.setPhone(user.getPhone());
            List<LinkappUser> userList = linkappUserService.selectUsers(query);
            Assert.isTrue(userList.size() == 0, "系统查询到该手机号已存在");
        }
        //        admin@+随机5位数字
        user.setUsername(linkappTenantService.checkUsername());
        return user;
    }

  /**
   * 删除
   */
  @ApiOperation("删除")
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "")
  @PostMapping("delete")
  public RestMessage delete(
      @Validated(Delete.class) @RequestBody RestModel<LinkappUser> restModel) {
    LinkappUser user = restModel.getModel();
    LinkappUser old = linkappUserService.get(user.getId());
    LogHelper.setContent(LogOperateType.USER_DELETE,old.getNickname(),old.getPhone());
    return super.delete(user.getId());
  }


  /**
   * 修改个人信息
   */
  @ApiOperation("修改个人信息")
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "")
  @PutMapping("profile")
  public RestMessage profile(
      @Validated(Update.class) @RequestBody RestModel<LinkappUser> restModel) {
    LinkappUser user = restModel.getModel();
    LinkappUser old = linkappUserService.get(user.getId());
    LogHelper.setContent(LogOperateType.USER_UPDATE,old.getNickname(),old.getPhone());
    service().updateProfile(restModel.getModel());
    return RestBuilders.successMessage();
  }

  /**
   * 修改个人信息
   */
  @ApiOperation("修改个人信息")
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "修改信息")
  @PostMapping("updateAccount")
  public RestMessage updateAccount(String username, String newUsername) {
    if (newUsername.length() > 32 || newUsername.length() < 4) {
      Assert.hasLength("", "账号名长度4-32位");
    }
    LinkappUser user = new LinkappUser();
    user.setUsername(username);
    List<LinkappUser> users = service().selectUsers(user);
    if (users.isEmpty()) {
      return RestBuilders.failureMessage(username + "用户名不存在");
    }

    user = new LinkappUser();
    user.setUsername(newUsername);
    users = service().selectUsers(user);
    if (users.isEmpty()) {
      return RestBuilders.successBuilder().data(service().updateAccount(username, newUsername))
          .build();
    } else {
      return RestBuilders.failureMessage(newUsername + "用户名已使用");
    }

  }


  /**
   * 修改
   */
  @ApiOperation("修改")
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "修改用户")
  @PutMapping
  @Override
  public RestMessage update(
      @Validated({Update.class, Put.class}) @RequestBody RestModel<LinkappUser> restModel) {
    fillRoles(restModel);
    return super.update(restModel);
  }

  /**
   * 锁定
   *
   * @return REST消息
   */
  @ApiOperation("锁定")
  @ApiImplicitParam(name = "ids", value = "用户编号集合", required = true)
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "锁定用户")
  @PutMapping("lock")
  public RestMessage lock(@RequestBody List<Long> ids) {
    OperateArguments.add(ids);
    service().lockAll(ids);
    return RestBuilders.successMessage();
  }

  /**
   * 解锁
   *
   * @return REST消息
   */
  @ApiOperation("解锁")
  @ApiImplicitParam(name = "ids", value = "用户编号集合", required = true)
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "解锁用户")
  @PutMapping("unlock")
  public RestMessage unlock(@RequestBody List<Long> ids) {
    OperateArguments.add(ids);
    service().unlockAll(ids);
    return RestBuilders.successMessage();
  }

  /**
   * 修改密码
   *
   * @param restModel REST模型
   * @return REST消息
   */
  @ApiOperation("修改密码")
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "修改密码")
  @PutMapping("password")
  public RestMessage password(@Validated @RequestBody RestModel<ResetPasswordVo> restModel) {
    service().updatePassword(restModel.getModel());
    return RestBuilders.successMessage();
  }

  /**
   * 重置密码
   *
   * @param restModel REST模型
   * @return REST消息
   */
  @ApiOperation("重置密码")
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "重置密码")
  @PutMapping("reset")
  public RestMessage reset(@RequestBody RestModel<ResetPasswordVo> restModel) {
    service().resetPassword(restModel.getModel());
    return RestBuilders.successMessage();
  }

  /**
   * 按前端模型填充角色
   */
  private void fillRoles(RestModel<LinkappUser> restModel) {
    LinkappUser model = restModel.getModel();
    CriteriaMap attach = restModel.getAttach();
    List<Integer> roleIds = attach.getExpect(LinkappUser.Fields.roles);
    if (CollectionUtils.isEmpty(model.getRoles()) && !CollectionUtils.isEmpty(roleIds)) {
      List<Role> roles = roleIds.stream().map(String::valueOf).map(Long::valueOf).map(i -> {
        Role role = new Role();
        role.setId(i);
        return role;
      }).collect(Collectors.toList());
//            model.setRoles(roles);
    }
  }

  /**
   * 生成图片验证码（缓存）
   *
   * @return 图片验证码
   */
  @ApiOperation("忘记密码-生成图片验证码")
  @PostMapping("/verificationCode")
  public RestMessage generateImageVerificationCode() {
    return RestBuilders.successMessage(service().getImage());
  }

  /**
   * 生成验证码并发送到手机（缓存），生成验证码前先对表单校验
   *
   * @return 成功失败消息
   */
  @ApiOperation("忘记密码-生成短信验证码并发送")
  @PostMapping("/sendVerificationCode")
  public RestMessage sendVerificationCode(@RequestBody RestModel<LinkappUser> restModel) {
    service()
        .sendVerificationCode(restModel.getModel().getUsername(), restModel.getModel().getPhone(),
            restModel.getAttach().get("imageVode").toString());
    return RestBuilders.successMessage();
  }

  /**
   * 表单验证，图片验证码、用户名、手机号、验证码是否正确
   *
   * @return 成功失败消息
   */
  @ApiOperation("忘记密码-表单验证")
  @PostMapping("/verificationMessages")
  public RestMessage verificationMessages(@RequestBody RestModel<LinkappUser> restModel) {
    return RestBuilders
        .successMessage(service().verificationMessages(restModel.getModel().getUsername(),
            restModel.getModel().getPhone(),
            restModel.getAttach().getString("imageVode"),
            restModel.getAttach().get("code").toString()));
  }

  /**
   * 修改用户密码，若与旧密码重复，则返回提示
   *
   * @return 成功失败消息
   */
  @ApiOperation("忘记密码-修改用户密码")
  @PutMapping("/resetPassword")
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "重置密码")
  public RestMessage resetPassword(@RequestBody RestModel<LinkappUser> restModel) {
    service().forgetPassword(restModel.getModel().getUsername(),
        restModel.getModel().getPassword());
    return RestBuilders.successMessage();
  }

  @ApiOperation("用户数量统计")
  @RequestMapping("/auditUser")
  public RestMessage auditUser() {
    String currentDate = DateUtil.getCurrentDateStr(DateUtil.DATE_TIME_FORMAT_DAY);
    String dateExp = "%Y-%m";
    LinkappUser linkappUser = linkappUserContextProducer.getCurrent();
    String tenantId = linkappUser.getTenantId();
    Integer currentMonthCount = service().auditUser(currentDate, dateExp, tenantId);
    String lastDay = lastDay();
    dateExp = "%Y-%m-%d";
    Integer lastDayCount = service().auditUser(lastDay, dateExp, tenantId);
    Integer userCount = service().auditUser(null, null, tenantId);
    Map map = new HashMap();
    map.put("currentMonthCount", currentMonthCount);
    map.put("lastDayCount", lastDayCount);
    map.put("userCount", userCount);
    return RestBuilders.successBuilder().data(map).build();

  }

  @ApiOperation("根据用户ID获取用户")
  @RequestMapping("/selectUser/{id}")
  public RestMessage selectUser(@PathVariable Long id) {
    LinkappUser query = new LinkappUser();
    query.setId(id);
    List<LinkappUser> users = service().selectUsers(query);
    if (ObjectUtils.isNotEmpty(users)) {
      return RestBuilders.successBuilder().data(users.get(0)).build();
    } else {
      return RestBuilders.failureBuilder().message("用户为空").build();
    }

  }

  @ApiOperation("根据查询条件查询用户")
  @RequestMapping("/selectUsers")
  public RestMessage selectUsers(@RequestBody RestModel<LinkappUser> restModel) {
    String tenantId = linkappUserContextProducer.getCurrent().getTenantId();
    LinkappUser user = restModel.getModel();
    if (user == null) {
      user = new LinkappUser();
    }
    user.setTenantId(tenantId);
    List<LinkappUser> users = service().selectUsersSorted(user);
    if (!users.isEmpty()) {
      return RestBuilders.successBuilder().data(users).build();
    } else {
      return RestBuilders.failureBuilder().message("用户为空").build();
    }

  }

  @ApiOperation("验证用户名是否可用")
  @RequestMapping("/checkUser/{username}")
  public RestMessage checkUser(@PathVariable String username) {
    String tenantId = linkappUserContextProducer.getCurrent().getTenantId();
    LinkappUser user = new LinkappUser();
    user.setTenantId(tenantId);
    user.setUsername(username);
    List<LinkappUser> users = service().selectUsers(user);
    if (users.isEmpty()) {
      return RestBuilders.successBuilder().message("用户名可以使用").build();
    } else {
      return RestBuilders.failureBuilder().message("用户名已存在").build();
    }
  }

  @ApiOperation("获取用户分页列表")
  @PostMapping("/selectPage")
  public RestMessage selectPage(@RequestBody RequestModel<LinkappUser> requestModel) {
    Assert.notNull(requestModel.getCustomQueryParams(), "customQueryParams 不能为空");
    Assert.notNull(requestModel.getPage(), "page 不能为空");
    IPage<LinkappUser> record = service().selectUsersPage(requestModel.getPage(),
        requestModel.getCustomQueryParams());
    return RestBuilders.successBuilder().data(record).build();
  }

  @ApiOperation("根据角色获取用户分页列表")
  @PostMapping("/selectUserByRolePage")
  public RestMessage selectUserByRolePage(@RequestBody RequestModel<LinkappRole> requestModel) {
    Assert.notNull(requestModel.getCustomQueryParams(), "customQueryParams 不能为空");
    Assert.notNull(requestModel.getPage(), "page 不能为空");
    IPage<LinkappUser> record = service().selectUserByRolePage(requestModel.getPage(),
        requestModel.getCustomQueryParams());
    return RestBuilders.successBuilder().data(record).build();
  }

  @ApiOperation("修改、新增用户角色关联")
  @PostMapping("user2Roles")
  public RestMessage user2Roles(@RequestBody UserRefRoleDTO userRefRole) {
    service().user2Roles(userRefRole.getUser(), userRefRole.getRoles());
    return RestBuilders.successMessage();
  }

  @ApiOperation("发送手机验证码根据类型")
  @RequestMapping("/verificationCode/{phone}/{type}")
  public RestMessage verificationCode(@PathVariable String phone, @PathVariable Integer type) {
    LinkappUser checkUser = new LinkappUser();
    checkUser.setPhone(phone);
    List<LinkappUser> users = service().selectUsers(checkUser);
    //type  0 reg,1 login 2 bind phone
    if (type == 0) {
      if (users.isEmpty()) {
        int randomInt = (int) ((Math.random() * 999999));
        String randomNo = String.format("%6d", randomInt).replace(" ", "0");
//        n 分钟过期
        redisUtil.set(phone, randomNo, 15 * 60);
        sendMessageUtil.sendVerificationCode(phone, randomNo);
        return RestBuilders.successMessage();
      } else {
        return RestBuilders.failureBuilder().message("手机号已绑定").build();
      }
    } else if( type == 2){
      LinkappUser curUser = linkappUserContextProducer.getCurrent();
      if (curUser == null) {
        return RestBuilders.failureBuilder().message("获取当前用户为空").build();
      }
      String curTenantId = curUser.getTenantId();
      if (StringUtils.isBlank(curTenantId)) {
        return RestBuilders.failureBuilder().message("获取当前项目为空").build();
      }
      checkUser.setPhone(phone);
      checkUser.setTenantId(curTenantId);
      users = service().selectUsers(checkUser);
      if (CollectionUtil.isNotEmpty(users)) {
        return RestBuilders.failureBuilder().message("手机号已绑定当前项目").build();
      }else {
        return initPhoneVerificationCode(type,phone);
      }
    }else {
      if (!users.isEmpty()) {
        int randomInt = (int) ((Math.random() * 999999));
        String randomNo = String.format("%6d", randomInt).replace(" ", "0");
//        redisUtil.set(phone, randomNo, 300);
        redisUtil.set(phone, randomNo, 15 * 60);
        sendMessageUtil.sendVerificationCode(phone, randomNo);
        return RestBuilders.successMessage();
      } else {
        return RestBuilders.failureBuilder().message("手机号不存在").build();
      }
    }
  }

  /**
   * 初始化手机验证码
   * @param type 业务type
   * @param phone 电话号码
   * @return 统一出参
   */
  private RestMessage initPhoneVerificationCode(Integer type, String phone) {
    int randomInt = (int) ((Math.random() * 999999));
    String randomNo = String.format("%6d", randomInt).replace(" ", "0");
    long time = 300;
    String key = phone;
    switch (type){
      case 2:
        //根据业务，特殊处理key等等
        break;
      default:
        break;
    }

    redisUtil.set(phone, randomNo, time);
    sendMessageUtil.sendVerificationCode(key, randomNo);
    return RestBuilders.successMessage();
  }

  @ApiOperation("绑定手机")
  @PostMapping("/bindPhone")
  public RestMessage bindPhone(@RequestBody RestModel<LinkappUser> restModel) {
    LinkappUser curUser = linkappUserContextProducer.getCurrent();
    if (curUser == null) {
      return RestBuilders.failureBuilder().message("获取当前用户为空").build();
    }
    String curTenantId = curUser.getTenantId();
    if (StringUtils.isBlank(curTenantId)) {
      return RestBuilders.failureBuilder().message("获取当前项目为空").build();
    }

    LinkappUser user = restModel.getModel();
    String phone = user.getPhone();
    Object obj = redisUtil.get(phone);
    if (obj == null) {
      return RestBuilders.failureMessage();
    } else {
      if (user.getVerificationCode().equals(obj.toString())) {
        LinkappUser checkUser = new LinkappUser();
        checkUser.setPhone(phone);
        List<LinkappUser> users = service().selectUsers(checkUser);
        if (users.isEmpty()) {
          service().updateProfile(restModel.getModel());
          return RestBuilders.successMessage();
        } else {
          //return RestBuilders.failureBuilder().message("手机号已存在").build();
          //20220630变更：比较手机号 + tenantId，已存在提示已存在，不存在，获取该手机号其他账号密码，设置到这个账号
          boolean isExist = false;
          for (int i = 0;i < users.size();i++){
            LinkappUser tmpUser = users.get(i);
            String otherTenantId = tmpUser.getTenantId();
            if (otherTenantId.equals(curTenantId)){
              isExist = true;
              break;
            }
            restModel.getModel().setPassword(tmpUser.getPassword());
          }
          //如果这个项目下已存在这个手机号
          if (isExist){
            return RestBuilders.failureBuilder().message("当前项目项目下手机号已存在").build();
          }
          //更新
          service().updateProfile(restModel.getModel());
          return RestBuilders.successMessage();
        }
      } else {
        return RestBuilders.failureMessage("验证码错误");
      }
    }
  }


  private String lastDay() {
    Calendar calendar = Calendar.getInstance();
    //得到度前一天
    calendar.add(Calendar.DATE, -1);
    Date date = calendar.getTime();
    DateFormat df = new SimpleDateFormat(DateUtil.DATE_TIME_FORMAT_DAY);
    return df.format(date);
  }

  /**
   * 修改个人信息-大屏图标显示
   */
  @ApiOperation("修改个人信息:大屏图标显示")
  @PostMapping("userIsShowScreen")
  public RestMessage updateUserIsShowScreen(@RequestBody RestModel<LinkappUser> restModel) {
    service().updateUserIsShowScreen(restModel.getModel());
    return RestBuilders.successMessage();
  }

  /**
   * 重置密码，手机号相同用户的密码都统一重置
   *
   * @return 成功失败消息
   */
  @ApiOperation("重置密码-修改用户密码")
  @PutMapping("/resetPasswordByVerificationCode")
  @CommonOperateLogAnnotate(module = LogModule.USER, desc = "用验证码重置密码")
  public RestMessage resetPasswordByVerificationCode(
      @RequestBody RestModel<LinkappUser> restModel) {
    return service().resetPasswordByVerificationCode(restModel.getModel().getPhone(),
        restModel.getModel().getPassword(), restModel.getAttach().getString("verificationCode"));
    //return RestBuilders.successMessage();
  }

  /**
   * 批量导入劳务公司
   * type = 1 为覆盖
   */
  @PostMapping("import")
  @ApiOperation("批量导入")
  public RestMessage importExcel(@NotNull @RequestPart("file") MultipartFile file, Integer type)throws Exception {
    //获取当前时间的时间
    Calendar calendar = Calendar.getInstance();
    SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
    String key = "linkappUser:"+formatter.format(calendar.getTime());
    AsyncUtil.submitTask(key,() ->{
      ExcelResultDTO resultDTO;
      try {
        resultDTO = linkappUserService.importExcel(file,type);
      } catch (Exception e) {
        throw new BusinessException(e.getMessage());
      }
      return resultDTO;
    });
    return RestBuilders.successBuilder().data(key).build();
  }

  /**
   * @Description: 下载模板
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @GetMapping("exportTemplate")
  @ApiOperation("下载模板")
  public void exportTemplate(HttpServletRequest request, HttpServletResponse response) {
    //  标题下的小标信息，可做统计数据展示
    List<String> stringList = new ArrayList<String>();
    stringList.add("注意事项");
    stringList.add("A.批量导入用户账号，角色分配输入项目已设置的角色编码");
    stringList.add("B.默认生成密码：abc@123");
    stringList.add("C.一个账号如有多个角色，使用英文状态下的，分隔开");
    String title = "用户批量导入模板";
    String fileName = "用户批量导入模板.xlsx";
    try {
      OutputStream outputStream = OutputStreamUtil
          .getOutputStream(request, response, fileName);
      String keyValue = "用户姓名（必填*）:nickname,手机号码（必填*）:phone,角色分配（必填*）:roleNames,单位（非必填）:companyName,性别（非必填）:sex";
      ExcelTools
          .exportExcelV2(outputStream, keyValue, LinkappUserDTO.creatExcel(), ExcelConstant.XLSX,
              title, stringList);
      response.flushBuffer();
      outputStream.close();
    } catch (IOException e) {
      throw new RuntimeException("excel导出失败！IOException异常");
    } catch (Exception e) {
      throw new RuntimeException("excel导出失败！");
    }
  }
}
